/**
 * 精确度保留方案
 * 
 * @description
 * 通过四舍五入到固定小数位来确保一致性
 * 
 * 优点：
 * - 实现简单
 * - 性能接近浮点数（约 80-90%）
 * - 数值范围大
 * - 易于调试
 * 
 * 缺点：
 * - 可能累积误差
 * - 依赖平台 Math 实现
 * - 极端情况可能不一致
 */

export class PrecisionNumber {
    
    /** 默认保留小数位数 */
    static PRECISION = 6;
    
    /** 缩放因子 */
    private static get SCALE(): number {
        return Math.pow(10, PrecisionNumber.PRECISION);
    }
    
    /** 内部值 */
    public value: number;
    
    constructor(value: number = 0) {
        this.value = PrecisionNumber.round(value);
    }
    
    /**
     * 核心：四舍五入到固定精度
     */
    static round(value: number): number {
        return Math.round(value * this.SCALE) / this.SCALE;
    }
    
    /**
     * 设置全局精度
     */
    static setPrecision(digits: number): void {
        if (digits < 0 || digits > 15) {
            throw new Error("Precision must be between 0 and 15");
        }
        this.PRECISION = digits;
    }
    
    /**
     * 从普通数字创建
     */
    static fromNumber(value: number): PrecisionNumber {
        return new PrecisionNumber(value);
    }
    
    /**
     * 转换为普通数字
     */
    toNumber(): number {
        return this.value;
    }
    
    /**
     * 加法
     */
    add(other: PrecisionNumber): PrecisionNumber {
        return new PrecisionNumber(this.value + other.value);
    }
    
    /**
     * 减法
     */
    sub(other: PrecisionNumber): PrecisionNumber {
        return new PrecisionNumber(this.value - other.value);
    }
    
    /**
     * 乘法
     */
    mul(other: PrecisionNumber): PrecisionNumber {
        return new PrecisionNumber(this.value * other.value);
    }
    
    /**
     * 除法
     */
    div(other: PrecisionNumber): PrecisionNumber {
        if (other.value === 0) throw new Error("Division by zero");
        return new PrecisionNumber(this.value / other.value);
    }
    
    /**
     * 缩放
     */
    scale(factor: number): PrecisionNumber {
        return new PrecisionNumber(this.value * factor);
    }
    
    /**
     * 平方
     */
    square(): PrecisionNumber {
        return new PrecisionNumber(this.value * this.value);
    }
    
    /**
     * 平方根
     */
    sqrt(): PrecisionNumber {
        if (this.value < 0) throw new Error("Cannot take square root of negative");
        return new PrecisionNumber(Math.sqrt(this.value));
    }
    
    /**
     * 绝对值
     */
    abs(): PrecisionNumber {
        return new PrecisionNumber(Math.abs(this.value));
    }
    
    /**
     * 取反
     */
    neg(): PrecisionNumber {
        return new PrecisionNumber(-this.value);
    }
    
    /**
     * 比较：小于
     */
    lt(other: PrecisionNumber): boolean {
        return this.value < other.value;
    }
    
    /**
     * 比较：大于
     */
    gt(other: PrecisionNumber): boolean {
        return this.value > other.value;
    }
    
    /**
     * 比较：等于
     */
    eq(other: PrecisionNumber): boolean {
        return this.value === other.value;
    }
    
    /**
     * 克隆
     */
    clone(): PrecisionNumber {
        return new PrecisionNumber(this.value);
    }
    
    /**
     * 转换为字符串
     */
    toString(): string {
        return this.value.toFixed(PrecisionNumber.PRECISION);
    }
    
    /**
     * Sin 函数
     */
    sin(): PrecisionNumber {
        return new PrecisionNumber(Math.sin(this.value));
    }
    
    /**
     * Cos 函数
     */
    cos(): PrecisionNumber {
        return new PrecisionNumber(Math.cos(this.value));
    }
    
    /**
     * Atan2 函数
     */
    static atan2(y: PrecisionNumber, x: PrecisionNumber): PrecisionNumber {
        return new PrecisionNumber(Math.atan2(y.value, x.value));
    }
    
    // 常量
    static readonly PI = new PrecisionNumber(Math.PI);
    static readonly E = new PrecisionNumber(Math.E);
    static readonly ZERO = new PrecisionNumber(0);
    static readonly ONE = new PrecisionNumber(1);
}

